package com.yc.cloud.openai.portal.utils;


import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientRequestException;

import com.yc.cloud.common.basic.api.ResponseResult;
import com.yc.cloud.common.basic.exception.Asserts;

import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;

@Component
@Slf4j
public class WebClientUtil {

    private final WebClient webClient;

    // 使用默认配置的 WebClient 构造函数
    public WebClientUtil(WebClient webClient) {
        this.webClient = webClient;
    }


    // GET 请求示例
    public <T> T get(String uri, Class<T> responseType) {
        return webClient
                .get()
                .uri(uri)
                .retrieve()
                .bodyToMono(responseType)
                .block(); // 阻塞，等待结果返回
    }

    // POST 请求示例
    public <T, R> T postJSON(String uri, R requestBody, Class<T> responseType) {
        try {
            return webClient
                    .post()
                    .uri(uri)
                    .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) // 明确设置请求头
                    .body(Mono.just(requestBody), responseType)
                    .retrieve()
                    .bodyToMono(responseType)
                    .block(); // 阻塞，等待结果返回
        } catch (WebClientRequestException ex) {
            log.error("WebClientUtil POST API JSON 请求失败：{}", ex.getMessage());
            Asserts.fail("服务不可用，请稍后再试。");
            return null;
        }

    }

    // 异步 GET 请求示例
    public <T> Mono<T> getAsync(String uri, Class<T> responseType) {
        return webClient
                .get()
                .uri(uri)
                .retrieve()
                .bodyToMono(responseType); // 返回 Mono<T>，调用者处理异步
    }

    // 异步 POST 请求示例
    public <T, R> Mono<T> postAsync(String uri, R requestBody, Class<T> responseType) {
        return webClient
                .post()
                .uri(uri)
                .body(Mono.just(requestBody), responseType)
                .retrieve()
                .bodyToMono(responseType); // 返回 Mono<T>，调用者处理异步
    }

    // 处理 application/x-www-form-urlencoded POST 请求
    public <T> T postFormData(String url, MultiValueMap<String, Object> formData, Class<T> responseType) {
        return webClient.post()
                .uri(url)
                .contentType(MediaType.MULTIPART_FORM_DATA)
                .body(BodyInserters.fromMultipartData(formData))
                .retrieve()
                .bodyToMono(responseType)
                .doOnError(WebClientRequestException.class, ex -> {
                    log.error("表单请求失败:{}", ex.getMessage());
                    // throw new RuntimeException("服务不可用，请稍后再试。", ex);
                    Asserts.fail("服务不可用，请稍后再试。");
                })
                .block(); // 阻塞获取结果
    }


    // 新增方法：发起 GET 请求并返回字节数组
    public byte[] getForBytes(String url) {
        return webClient.get()
                .uri(url)
                .retrieve()
                .bodyToMono(byte[].class)
                .block(); // 阻塞获取结果
    }

    // 自定义异常类，用于包装 ErrorResponse
    public static class CustomWebClientException extends RuntimeException {
        private final ResponseResult errorResponse;

        public CustomWebClientException(ResponseResult errorResponse) {
            super(errorResponse.getMessage());
            this.errorResponse = errorResponse;
        }

        public ResponseResult getErrorResponse() {
            return errorResponse;
        }
    }
}

